'use client';

import {isToday, isYesterday, subMonths, subWeeks} from 'date-fns';
import {useParams, useRouter} from 'next/navigation';
import {useState} from 'react';
import {toast} from 'sonner';
import {motion} from 'framer-motion';
import {
    AlertDialog,
    AlertDialogAction,
    AlertDialogCancel,
    AlertDialogContent,
    AlertDialogDescription,
    AlertDialogFooter,
    AlertDialogHeader,
    AlertDialogTitle
} from '@/components/ui/alert-dialog';
import {SidebarGroup, SidebarGroupContent, SidebarMenu, useSidebar} from '@/components/ui/sidebar';
import {ChatItem} from './sidebar-history-item';
import {LoaderIcon} from './icons';
import {useGetChatHistory} from '@/hooks/query/use-chat';
import type {Chat} from '@/types/interfaces';
import apiClient from "@/lib/axios";

type GroupedChats = {
    today: Chat[];
    yesterday: Chat[];
    lastWeek: Chat[];
    lastMonth: Chat[];
    older: Chat[];
};

export interface ChatHistory {
    chats: Array<Chat>;
    hasMore: boolean;
}

const groupChatsByDate = (chats: Chat[]): GroupedChats => {
    const now = new Date();
    const oneWeekAgo = subWeeks(now, 1);
    const oneMonthAgo = subMonths(now, 1);

    return chats.reduce(
        (groups, chat) => {
            const chatDate = new Date(chat.createdAt);

            if (isToday(chatDate)) {
                groups.today.push(chat);
            } else if (isYesterday(chatDate)) {
                groups.yesterday.push(chat);
            } else if (chatDate > oneWeekAgo) {
                groups.lastWeek.push(chat);
            } else if (chatDate > oneMonthAgo) {
                groups.lastMonth.push(chat);
            } else {
                groups.older.push(chat);
            }

            return groups;
        },
        {
            today: [],
            yesterday: [],
            lastWeek: [],
            lastMonth: [],
            older: []
        } as GroupedChats
    );
};

export function SidebarHistory() {
    const {projectId}: { projectId: string } = useParams();
    const {setOpenMobile} = useSidebar();
    const {id} = useParams();

    const {data: paginatedChatHistories, setSize, isValidating, isLoading, mutate} = useGetChatHistory(projectId);

    const router = useRouter();
    const [deleteId, setDeleteId] = useState<string | null>(null);
    const [showDeleteDialog, setShowDeleteDialog] = useState(false);

    const hasReachedEnd = paginatedChatHistories ? paginatedChatHistories.some(page => page.hasMore === false) : false;

    const hasEmptyChatHistory = paginatedChatHistories
        ? paginatedChatHistories.every(page => page.chats.length === 0)
        : false;

    const handleDelete = async () => {

        toast.promise(apiClient.delete(`/${projectId}/chat/${deleteId}`), {
            loading: 'Deleting chat...',
            success: () => {
                mutate(chatHistories => {
                    if (chatHistories) {
                        return chatHistories.map(chatHistory => ({
                            ...chatHistory,
                            chats: chatHistory.chats.filter(chat => chat.id !== deleteId)
                        }));
                    }
                });

                return 'Chat deleted successfully';
            },
            error: 'Failed to delete chat'
        });

        setShowDeleteDialog(false);

        if (deleteId === id) {
            router.push(`/project/${projectId}/chat`);
        }
    };

    if (isLoading) {
        return (
            <SidebarGroup>
                <div className="px-2 py-1 text-xs text-sidebar-foreground/50">Today</div>
                <SidebarGroupContent>
                    <div className="flex flex-col">
                        {[44, 32, 28, 64, 52].map(item => (
                            <div key={item} className="rounded-md h-8 flex gap-2 px-2 items-center">
                                <div
                                    className="h-4 rounded-md flex-1 max-w-[--skeleton-width] bg-sidebar-accent-foreground/10"
                                    style={
                                        {
                                            '--skeleton-width': `${item}%`
                                        } as React.CSSProperties
                                    }
                                ></div>
                            </div>
                        ))}
                    </div>
                </SidebarGroupContent>
            </SidebarGroup>
        );
    }

    if (hasEmptyChatHistory) {
        return (
            <SidebarGroup>
                <SidebarGroupContent>
                    <div className="px-2 text-zinc-500 w-full flex flex-row justify-center items-center text-sm gap-2">
                        开始聊天后，对话内容将在此处显示！
                    </div>
                </SidebarGroupContent>
            </SidebarGroup>
        );
    }

    return (
        <>
            <SidebarGroup>
                <SidebarGroupContent>
                    <SidebarMenu>
                        {paginatedChatHistories &&
                            (() => {
                                const chatsFromHistory = paginatedChatHistories.flatMap(
                                    paginatedChatHistory => paginatedChatHistory.chats
                                );

                                const groupedChats = groupChatsByDate(chatsFromHistory);

                                return (
                                    <div className="flex flex-col gap-6">
                                        {groupedChats.today.length > 0 && (
                                            <div>
                                                <div className="px-2 py-1 text-xs text-sidebar-foreground/50">今天</div>
                                                {groupedChats.today.map(chat => (
                                                    <ChatItem
                                                        key={chat.id}
                                                        chat={chat}
                                                        isActive={chat.id === id}
                                                        onDelete={chatId => {
                                                            setDeleteId(chatId);
                                                            setShowDeleteDialog(true);
                                                        }}
                                                        setOpenMobile={setOpenMobile}
                                                    />
                                                ))}
                                            </div>
                                        )}

                                        {groupedChats.yesterday.length > 0 && (
                                            <div>
                                                <div className="px-2 py-1 text-xs text-sidebar-foreground/50">昨天</div>
                                                {groupedChats.yesterday.map(chat => (
                                                    <ChatItem
                                                        key={chat.id}
                                                        chat={chat}
                                                        isActive={chat.id === id}
                                                        onDelete={chatId => {
                                                            setDeleteId(chatId);
                                                            setShowDeleteDialog(true);
                                                        }}
                                                        setOpenMobile={setOpenMobile}
                                                    />
                                                ))}
                                            </div>
                                        )}

                                        {groupedChats.lastWeek.length > 0 && (
                                            <div>
                                                <div className="px-2 py-1 text-xs text-sidebar-foreground/50">
                                                    过去一周
                                                </div>
                                                {groupedChats.lastWeek.map(chat => (
                                                    <ChatItem
                                                        key={chat.id}
                                                        chat={chat}
                                                        isActive={chat.id === id}
                                                        onDelete={chatId => {
                                                            setDeleteId(chatId);
                                                            setShowDeleteDialog(true);
                                                        }}
                                                        setOpenMobile={setOpenMobile}
                                                    />
                                                ))}
                                            </div>
                                        )}

                                        {groupedChats.lastMonth.length > 0 && (
                                            <div>
                                                <div className="px-2 py-1 text-xs text-sidebar-foreground/50">
                                                    过去一个月
                                                </div>
                                                {groupedChats.lastMonth.map(chat => (
                                                    <ChatItem
                                                        key={chat.id}
                                                        chat={chat}
                                                        isActive={chat.id === id}
                                                        onDelete={chatId => {
                                                            setDeleteId(chatId);
                                                            setShowDeleteDialog(true);
                                                        }}
                                                        setOpenMobile={setOpenMobile}
                                                    />
                                                ))}
                                            </div>
                                        )}

                                        {groupedChats.older.length > 0 && (
                                            <div>
                                                <div className="px-2 py-1 text-xs text-sidebar-foreground/50">更早</div>
                                                {groupedChats.older.map(chat => (
                                                    <ChatItem
                                                        key={chat.id}
                                                        chat={chat}
                                                        isActive={chat.id === id}
                                                        onDelete={chatId => {
                                                            setDeleteId(chatId);
                                                            setShowDeleteDialog(true);
                                                        }}
                                                        setOpenMobile={setOpenMobile}
                                                    />
                                                ))}
                                            </div>
                                        )}
                                    </div>
                                );
                            })()}
                    </SidebarMenu>

                    <motion.div
                        onViewportEnter={() => {
                            if (!isValidating && !hasReachedEnd) {
                                setSize(size => size + 1);
                            }
                        }}
                    />

                    {hasReachedEnd ? (
                        <div
                            className="px-2 text-zinc-500 w-full flex flex-row justify-center items-center text-sm gap-2 mt-8">
                            已是聊天历史记录的末尾
                        </div>
                    ) : (
                        <div className="p-2 text-zinc-500 dark:text-zinc-400 flex flex-row gap-2 items-center mt-8">
                            <div className="animate-spin">
                                <LoaderIcon/>
                            </div>
                            <div>正在加载聊天记录...</div>
                        </div>
                    )}
                </SidebarGroupContent>
            </SidebarGroup>

            <AlertDialog open={showDeleteDialog} onOpenChange={setShowDeleteDialog}>
                <AlertDialogContent>
                    <AlertDialogHeader>
                        <AlertDialogTitle>你确定要删除此聊天记录吗？</AlertDialogTitle>
                        <AlertDialogDescription>此操作无法撤销。这将永久删除您的聊天记录。</AlertDialogDescription>
                    </AlertDialogHeader>
                    <AlertDialogFooter>
                        <AlertDialogCancel>Cancel</AlertDialogCancel>
                        <AlertDialogAction onClick={handleDelete}>Continue</AlertDialogAction>
                    </AlertDialogFooter>
                </AlertDialogContent>
            </AlertDialog>
        </>
    );
}
